package org.tis.tools.abf.module.ac.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.tis.tools.abf.module.ac.controller.request.AcDeleteListRequest;
import org.tis.tools.abf.module.ac.controller.request.AcRoleAddRequest;
import org.tis.tools.abf.module.ac.controller.request.AcRoleMoveRequest;
import org.tis.tools.abf.module.ac.controller.request.AcRoleTreeFilterRequest;
import org.tis.tools.abf.module.ac.dao.AcRoleMapper;
import org.tis.tools.abf.module.ac.entity.AcOperatorRole;
import org.tis.tools.abf.module.ac.entity.AcRole;
import org.tis.tools.abf.module.ac.entity.AcRoleFunc;
import org.tis.tools.abf.module.ac.exception.AcExceptionCodes;
import org.tis.tools.abf.module.ac.exception.AcRoleManagementException;
import org.tis.tools.abf.module.ac.service.IAcOperatorRoleService;
import org.tis.tools.abf.module.ac.service.IAcRoleFuncService;
import org.tis.tools.abf.module.ac.service.IAcRoleService;
import org.tis.tools.abf.module.common.entity.Tree;
import org.tis.tools.abf.module.common.entity.enums.YON;
import org.tis.tools.abf.module.common.entity.vo.TreeDetail;
import org.tis.tools.abf.module.sys.entity.SysDictItem;
import org.tis.tools.abf.module.sys.service.ISysDictItemService;
import org.tis.tools.abf.module.sys.service.ISysDictService;
import org.tis.tools.core.utils.StringUtil;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static org.tis.tools.core.utils.BasicUtil.wrap;

/**
 * acRole的Service接口实现类
 * 
 * @author Auto Generate Tools
 * @date 2018/04/23
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class AcRoleServiceImpl extends ServiceImpl<AcRoleMapper, AcRole> implements IAcRoleService {

    @Autowired
    IAcRoleFuncService acRoleFuncService;
    @Autowired
    IAcRoleService acRoleService;
    @Autowired
    private IAcOperatorRoleService acOperatorRoleService;
    @Autowired
    private ISysDictItemService sysDictItemService;
    @Autowired
    private ISysDictService sysDictService;


    /**
     * 根据条件查询角色
     */
    @Override
    public AcRole queryByCondition(AcRole acRole) throws AcRoleManagementException{

        EntityWrapper<AcRole> acRoleEntityWrapper = new EntityWrapper<>();
        if(StringUtils.isNotBlank(acRole.getRoleCode())){
            acRoleEntityWrapper.eq(AcRole.COLUMN_ROLE_CODE, acRole.getRoleCode());
        }
        if(StringUtils.isNotBlank(acRole.getRoleName())){
            acRoleEntityWrapper.eq(AcRole.COLUMN_ROLE_NAME, acRole.getRoleName());
        }
        AcRole acRole1 = selectOne(acRoleEntityWrapper);
        return acRole1;
    }

    /**
     * 新建一个角色
     */
    @Override
    public AcRole createAcRole(AcRoleAddRequest request) throws  AcRoleManagementException {
        AcRole acRole = new AcRole();
        acRole.setRoleCode(request.getRoleCode());
        acRole.setRoleName(request.getRoleName());
        if (null != request.getEnabled()){
            acRole.setEnabled(request.getEnabled());
        }else {
            acRole.setEnabled(YON.YES);
        }
        acRole.setRoleDesc(request.getRoleDesc());
        acRole.setRoleGroup(request.getRoleGroup());
        insert(acRole);
        return acRole;
    }
    /**
     * 根据Guid修改一个角色
     */
    @Override
    public boolean updateAcRole(AcRole acRole) throws AcRoleManagementException {

        //判断角色代码是否已经存在
        EntityWrapper<AcRole> acRoleEntityWrapper = new EntityWrapper<>();
        acRoleEntityWrapper.eq(AcRole.COLUMN_ROLE_CODE,acRole.getRoleCode());
        acRoleEntityWrapper.notIn(AcRole.COLUMN_GUID,acRole.getGuid());
        List<AcRole> acRoleList = selectList(acRoleEntityWrapper);
        if (0 != acRoleList.size()){
            throw new AcRoleManagementException(AcExceptionCodes.ROLE_CODE_IS_EXIST);
        }
        boolean bolen = updateById(acRole);
        return bolen;
    }
    /**
     * 根据roleCode删除一个角色
     */
    @Override
    public boolean deleteByRoleCode(String id) throws AcRoleManagementException {

            //删除掉权限集(角色)功能对应关系数据
            Wrapper<AcRoleFunc> wrapper = new EntityWrapper<AcRoleFunc>();
            wrapper.eq(AcRoleFunc.COLUMN_GUID_ROLE,id);
            List<AcRoleFunc> list = acRoleFuncService.selectList(wrapper);
            if (0 != list.size()){
                for (AcRoleFunc acRoleFunc : list){
                    if (null != acRoleFunc){
                        acRoleFuncService.deleteRoleFunc(acRoleFunc.getGuid());
                    }
                }
            }
            //删除操作员与权限集（角色）对应关系数据
            Wrapper<AcOperatorRole> wrapperOper = new EntityWrapper<AcOperatorRole>();
            wrapperOper.eq(AcOperatorRole.COLUMN_GUID_ROLE,id);
            List<AcOperatorRole> listRole = acOperatorRoleService.selectList(wrapperOper);
            if (0 != listRole.size()){
                for (AcOperatorRole acOperatorRole : listRole){
                    if (null != acOperatorRole){
                        acOperatorRoleService.deleteOperatorRole(acOperatorRole.getGuid());
                    }
                }
            }

            //删除角色
            boolean bolen = deleteById(id);
            return bolen;
    }

    /**
     * 批量删除
     */
    @Override
    public void batchDelete(AcDeleteListRequest listRequest) throws AcRoleManagementException {

        if (0 == listRequest.getDeleteList().size()){
            throw new AcRoleManagementException(AcExceptionCodes.PARAMETER_IS_EMPTY_WHRN_BATCH_DELETE,wrap("删除时参数列表为空"));
        }
        for (String roleGuid : listRequest.getDeleteList()){
            if (!StringUtil.isEmpty(roleGuid)){
                AcRole acRole = selectById(roleGuid);
                if (null == acRole){
                    throw new AcRoleManagementException(AcExceptionCodes.FAILURE_WHEN_QUERY_AC_ROLE,wrap
                            ("删除的列表中有不存在或已删除的角色！"));
                }
            }
        }

        for(String roleGuid : listRequest.getDeleteList()){
            if (!StringUtil.isEmpty(roleGuid)){
                deleteByRoleCode(roleGuid);
            }
        }
    }

    /**
     * 查询角色树
     */
    @Override
    public List<Object> queryRoleTree() throws AcRoleManagementException {

        //查询角色中有几种分组
        List<String> distinctGroupList = this.baseMapper.queryDistinctRoleGroup();
        //为了避免查询回来的数组还有重复值
        Set<String> set = new HashSet<String>(distinctGroupList);
        distinctGroupList.clear();
        distinctGroupList.addAll(set);

        List<Object> list = new ArrayList<Object>();
        for(String groupName : distinctGroupList){
            if (StringUtil.isNotNull(groupName)){
                    TreeDetail treeDetail = new TreeDetail();
                    treeDetail.setLabel(groupName);

                    //获取分组的GUID,以便删除使用
                    Wrapper<SysDictItem> itemWrapper = new EntityWrapper<SysDictItem>();
                    itemWrapper.eq(SysDictItem.COLUMN_ITEM_NAME,groupName);
                    itemWrapper.eq(SysDictItem.COLUMN_GUID_DICT,"1029673332138020866");

                    List<SysDictItem> dictItemList = sysDictItemService.selectList(itemWrapper);
                    if (0 != dictItemList.size()){
                        SysDictItem sysDictItem = dictItemList.get(0);
                        if (null != sysDictItem){
                            treeDetail.setGuid(sysDictItem.getGuid());
                        }
                    }

                    //查询该分组下对应的角色
                    Wrapper<AcRole> wrapper = new EntityWrapper<AcRole>();
                    wrapper.eq(AcRole.COLUMN_ROLE_GROUP,groupName);

                    List<Tree> treeList = new ArrayList<Tree>();

                    List<AcRole> roleList = selectList(wrapper);
                    //将查询出来的角色放到列表中
                    treeList = treeStructure(roleList);

                    treeDetail.setChildren(treeList);
                    list.add(treeDetail);
            }else {

            }
        }

        //查询无分组下的角色
        Wrapper<AcRole> wrapper = new EntityWrapper<AcRole>();
        wrapper.isNull(AcRole.COLUMN_ROLE_GROUP);

        List<AcRole> roleList = selectList(wrapper);

        for (AcRole acRole :roleList){
            if (null != acRole){
                Tree tree = new Tree();
                tree.setGuid(acRole.getGuid());
                tree.setLabel(acRole.getRoleName());
                tree.setData(acRole.getEnabled().toString());
                list.add(tree);
            }
        }

        return list;
    }

    /**
     * 根据条件查询角色树
     * 业务逻辑:角色树上展示所有未删除的角色,和角色是否启用无关
     */
    @Override
    public List<Object> queryRoleTreeFilter(AcRoleTreeFilterRequest treeFilterRequest) throws AcRoleManagementException {

        List<SysDictItem> sysDictItemList = new ArrayList<SysDictItem>();
        sysDictItemList = sysDictItemService.querySysDictItemsByKey("DICT_ROLE_GROUP");

        //查询角色中有几种分组
        List<String> distinctGroupList = this.baseMapper.queryDistinctRoleGroup();
        //为了避免查询回来的数组还有重复值
        Set<String> set = new HashSet<String>(distinctGroupList);
        distinctGroupList.clear();
        distinctGroupList.addAll(set);

        List<Object> list = new ArrayList<Object>();
        List<String> groupNameList = new ArrayList<String>();
        for(String groupName : distinctGroupList){
            if (StringUtil.isNotNull(groupName)){
                TreeDetail treeDetail = new TreeDetail();
                treeDetail.setLabel(groupName);

                //获取分组的GUID,以便删除使用
                Wrapper<SysDictItem> itemWrapper = new EntityWrapper<SysDictItem>();
                itemWrapper.eq(SysDictItem.COLUMN_ITEM_NAME,groupName);
                itemWrapper.eq(SysDictItem.COLUMN_GUID_DICT,"1029673332138020866");

                List<SysDictItem> dictItemList = sysDictItemService.selectList(itemWrapper);
                if (0 != dictItemList.size()){
                    SysDictItem sysDictItem = dictItemList.get(0);
                    if (null != sysDictItem){
                        treeDetail.setGuid(sysDictItem.getGuid());
                    }
                }

                //查询该分组下对应的角色
                Wrapper<AcRole> wrapper = new EntityWrapper<AcRole>();
                wrapper.eq(AcRole.COLUMN_ROLE_GROUP,groupName);
                if (!StringUtil.isEmpty(treeFilterRequest.getName())){
                    wrapper.like(AcRole.COLUMN_ROLE_NAME,treeFilterRequest.getName());
                }
                wrapper.orderBy(AcRole.COLUMN_CREATETIME,true);

                List<AcRole> roleList = selectList(wrapper);
                if (0 == roleList.size()){
                    continue;
                }

                //将查询出来的角色放到列表中
                groupNameList.add(groupName);
                List<Tree> treeList = treeStructure(roleList);
                treeDetail.setChildren(treeList);
                list.add(treeDetail);
            }
        }

        //将没有角色的分组展示出来,如果根据姓名迷糊查询则不需要展示多于的分组
        if (StringUtil.isEmpty(treeFilterRequest.getName())){
            if (0 != sysDictItemList.size()){
                //查询出角色分组对应字典项的值
                Wrapper<SysDictItem> itemWrapper = new EntityWrapper<SysDictItem>();
                if (0 != groupNameList.size()){
                    itemWrapper.eq(SysDictItem.COLUMN_GUID_DICT,sysDictService.queryDictByKey("DICT_ROLE_GROUP").getGuid());
                    itemWrapper.in(SysDictItem.COLUMN_ITEM_NAME,groupNameList);
                }
                List<SysDictItem> distinctList = sysDictItemService.selectList(itemWrapper);

                //去除有角色的分组
                sysDictItemList.removeAll(distinctList);

                for (SysDictItem sysDictItem : sysDictItemList){
                    if (null != sysDictItem){
                        TreeDetail treeDetail = new TreeDetail();
                        treeDetail.setLabel(sysDictItem.getItemName());
                        treeDetail.setGuid(sysDictItem.getGuid());
                        list.add(treeDetail);
                    }
                }
            }
        }

        //处理无分组下的角色
        Wrapper<AcRole> wrapper = new EntityWrapper<AcRole>();
        wrapper.isNull(AcRole.COLUMN_ROLE_GROUP);
        if (!StringUtil.isEmpty(treeFilterRequest.getName())){
            wrapper.like(AcRole.COLUMN_ROLE_NAME,treeFilterRequest.getName());
        }
        wrapper.orderBy(AcRole.COLUMN_CREATETIME,true);

        List<AcRole> roleList = selectList(wrapper);

        for (AcRole acRole :roleList){
            if (null != acRole){
                Tree tree = new Tree();
                tree.setCode(acRole.getRoleCode());
                tree.setGuid(acRole.getGuid());
                tree.setLabel(acRole.getRoleName());
                tree.setData(acRole.getEnabled().toString());
                list.add(tree);
            }
        }
        return list;
    }

    /**
     * 将查询出来的角色放到列表中
     */
    private List<Tree> treeStructure(List<AcRole> roleList){

        List<Tree> treeList = new ArrayList<Tree>();

        //将查询出来的角色放到列表中
        for (AcRole acRole : roleList){
            if (null != acRole){
                Tree tree = new Tree();
                tree.setCode(acRole.getRoleCode());
                tree.setGuid(acRole.getGuid());
                tree.setLabel(acRole.getRoleName());
                tree.setData(acRole.getEnabled().toString());
                treeList.add(tree);
            }
        }

        return treeList;
    }

    /**
     * 根据条件查询操作员下的角色
     */
    @Override
    public Page<AcRole> queryByOperator(String operatorId, Page<AcRole> page, EntityWrapper<AcRole> wrapper) throws AcRoleManagementException {
        return page.setRecords(this.baseMapper.queryByOperator(page,operatorId,wrapper));
    }

    /**
     * 根据角色分组查询角色
     */
    @Override
    public List<AcRole> queryRolesByGroup(String roleGroup) throws AcRoleManagementException {

        List<AcRole> list = new ArrayList<AcRole>();

        Wrapper<AcRole> wrapper = new EntityWrapper<AcRole>();
        wrapper.eq(AcRole.COLUMN_ROLE_GROUP,roleGroup);

        list = selectList(wrapper);
        return list;
    }

    /**
     * 启用角色
     */
    @Override
    public AcRole enableRole(String id) throws AcRoleManagementException {

        AcRole acRoleQue = selectById(id);
        if (null == acRoleQue){
            throw new AcRoleManagementException(AcExceptionCodes.FAILURE_WHEN_QUERY_AC_ROLE,wrap("角色不存在或已被删除！"));
        }
        if (YON.YES.equals(acRoleQue.getEnabled())){
            throw new AcRoleManagementException(AcExceptionCodes.ROLE_STATE_IS_ENABLE,wrap("角色状态已是启用状态"));
        }
        acRoleQue.setEnabled(YON.YES);

        updateById(acRoleQue);
        return acRoleQue;
    }

    /**
     * 停用角色
     */
    @Override
    public AcRole disableRole(String id) throws AcRoleManagementException {
        AcRole acRoleQue = selectById(id);
        if (null == acRoleQue){
            throw new AcRoleManagementException(AcExceptionCodes.FAILURE_WHEN_QUERY_AC_ROLE,wrap("角色不存在或已被删除！"));
        }
        if (YON.NO.equals(acRoleQue.getEnabled())){
            throw new AcRoleManagementException(AcExceptionCodes.ROLE_STATE_IS_DISABLE,wrap("角色状态已是停用状态状态"));
        }
        acRoleQue.setEnabled(YON.NO);

        updateById(acRoleQue);
        return acRoleQue;
    }

    /**
     * 判断角色代码是否已经存在
     */
    @Override
    public Boolean existRoleCode(String roleCode) throws AcRoleManagementException {

        Boolean existRoleCode = false;

        Wrapper<AcRole> wrapper = new EntityWrapper<AcRole>();
        wrapper.eq(AcRole.COLUMN_ROLE_CODE,roleCode);
        AcRole acRole = selectOne(wrapper);

        if (null != acRole){
            existRoleCode = true;
        }

        return existRoleCode;
    }

    /**
     * 判断修改角色代码是否已经存在
     */
    @Override
    public Boolean existUpdateRoleCode(String roleCode, String guid) throws AcRoleManagementException {

        Wrapper<AcRole> wrapper = new EntityWrapper<AcRole>();
        wrapper.eq(AcRole.COLUMN_ROLE_CODE,roleCode);

        List<AcRole> roleList = selectList(wrapper);
        if (0 != roleList.size()){
            AcRole acRole = selectById(guid);
            if (null != acRole){
                roleList.remove(acRole);
                if (0 != roleList.size()){
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * 角色移动
     */
    @Override
    public void moveRoleToGroup(AcRoleMoveRequest acRoleMoveRequest) throws AcRoleManagementException {

        AcRole acRole = selectById(acRoleMoveRequest.getGuid());
        if (null == acRole){
            throw new AcRoleManagementException(AcExceptionCodes.FAILURE_WHEN_QUERY_AC_ROLE);
        }

        if (StringUtil.isEmpty(acRoleMoveRequest.getRoleGroup())){
            acRole.setRoleGroup(null);
        }else {
            acRole.setRoleGroup(acRoleMoveRequest.getRoleGroup());
        }
        updateAllColumnById(acRole);
    }
}

